#
#  F-Spot Plugin for XBMC
#  Copyright (C) 2009 forteresce@gmail.com
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#
# Thanks to Anoop Menon for the iPhoto plugin for xbmc.

__scriptname__ = "F-Spot Plugin for XBMC"
__author__     = "forteresce@gmail.com"
__url__        = "http://code.google.com/p/xbmc-fspot/"
__svn_url__    = "http://xbmc-fspot.googlecode.com/svn/trunk/"
__credits__    = "a lone leaf"
__version__    = "[Beta 1.0]"
__license__    = "GPL v2"

import sys
import os
import os.path
import traceback
import md5
import calendar

import xbmc
import xbmcgui as gui
import xbmcplugin as plugin

RESOURCE_PATH = xbmc.translatePath(os.path.join(os.getcwd(), "resources"))
ICONS_PATH = os.path.join(RESOURCE_PATH, "icons")
BASE_URL = "plugin://pictures/xbmc-fspot/"
PLATFORM = "Linux"
THUMBNAILS_PATH = os.path.join(os.path.expanduser('~'), '.thumbnails', 'large')

sys.path.append(os.path.join(RESOURCE_PATH, "platform_libraries", PLATFORM))

from fspotdb import FSpotDB

DEFAULT_DB_PATH = os.path.join(os.path.expanduser('~'), '.config', 'f-spot', 'photos.db')
DB_PATH = DEFAULT_DB_PATH #FIXME : Make this confiurable
UNTAGGED=-1

DEFAULT_TIME_ICON = os.path.join(ICONS_PATH, "time")
DEFAULT_FOLDER_ICON = os.path.join(ICONS_PATH, "albums")

db = FSpotDB(DB_PATH) #FIXME : The file may not exist

def get_params(paramstring):
    _debug(paramstring)
    params = {}
    paramstring = str(paramstring).strip()
    paramstring = paramstring.lstrip("?")

    if not paramstring:
        return params
    
    paramlist = paramstring.split("&")
    for param in paramlist:
        (k,v) = param.split("=")
        params[k] = v
    
    return params

def process_params(params):
    global UNTAGGED
    
    try:
        action = params['action']
    except:
        _error("No action specified")
        return mainmenu()

    if action == "showCategory":
        category = params['category']
        _debug("Fetching images for category: " + params['category']);
        
        photosInCategory(category)
    elif action == "listCategories":
        categories(0)
    elif action == "listYears":
        years()
    elif action == "listMonths":
        months(params['year'])
    elif action == "listDays":
        days(params['year'], params['month'])
    elif action == "showDate":
        photosOnDate(params['year'], params['month'], params['day'])
    else:
        mainmenu()

def photosInCategory(category):
    # get the photos in this categories and list them
    addPhotos(db.getPhotosInCategory(category))

def subcategories(parentName, parentId):
    global BASE_URL,DEFAULT_FOLDER_ICON
    
    # get the sub categories recursively
    for (id, name, icon) in db.getCategoriesUnder(parentId):
        if len(parentName) == 0 :
            displayName = name
        else :
            displayName = parentName + " > " + name
        item=gui.ListItem(displayName, iconImage=DEFAULT_FOLDER_ICON,thumbnailImage=DEFAULT_FOLDER_ICON + ".png")
        item.setInfo( type="pictures", infoLabels={ "Title": displayName })
        plugin.addDirectoryItem(handle = int(sys.argv[1]), url=BASE_URL+"?action=showCategory&category=%d" % (id), listitem = item, isFolder = True)
        subcategories(displayName, id)
    
def categories(parentId):
    global BASE_URL,DEFAULT_FOLDER_ICON,UNTAGGED
    
    # get the default categories and list them
    subcategories("", parentId)
    
    if parentId == 0:
        item=gui.ListItem("Untagged", iconImage=DEFAULT_FOLDER_ICON,thumbnailImage=DEFAULT_FOLDER_ICON + ".png")
        item.setInfo( type="pictures", infoLabels={ "Title": "Untagged" })
        plugin.addDirectoryItem(handle = int(sys.argv[1]), url=BASE_URL+"?action=showCategory&category=%d" % (UNTAGGED), listitem = item, isFolder = True)

def photosOnDate(year, month, day):    
    # get the photos on that day and list them
    addPhotos(db.getPhotosOnDate(year, month, day))
    
def addPhotos(data):
    global BASE_URL,THUMBNAILS_PATH

    for (id, uri, filename) in data:
        name = filename
        icon = os.path.join(THUMBNAILS_PATH, md5.new(uri+filename).hexdigest())
        _debug(icon)
        item=gui.ListItem(name, iconImage=icon, thumbnailImage=icon + ".png")
        item.setInfo( type="pictures", infoLabels={ "Title": name })
        plugin.addDirectoryItem(handle = int(sys.argv[1]), url=uri.lstrip("file://")+filename, listitem = item, isFolder = False)

def years():
    global BASE_URL,DEFAULT_TIME_ICON

    # get the years and display
    for (year,) in db.getYears():
        item=gui.ListItem("%s" % (year), iconImage=DEFAULT_TIME_ICON,thumbnailImage=DEFAULT_TIME_ICON + ".png")
        item.setInfo( type="pictures", infoLabels={ "Title": "%s" % (year) })
        plugin.addDirectoryItem(handle = int(sys.argv[1]), url=BASE_URL+"?action=listMonths&year=%s" % year, listitem = item, isFolder = True)

def months(year):
    global BASE_URL,DEFAULT_TIME_ICON

    # get the months and display
    for (month,) in db.getMonths(year):
        monthName = calendar.month_name[int("%s" % month)]
        item=gui.ListItem(monthName, iconImage=DEFAULT_TIME_ICON,thumbnailImage=DEFAULT_TIME_ICON + ".png")
        item.setInfo( type="pictures", infoLabels={ "Title": monthName })
        plugin.addDirectoryItem(handle = int(sys.argv[1]), url=BASE_URL+"?action=listDays&year=%s&month=%s" % (year,month), listitem = item, isFolder = True)

def days(year, month):
    global BASE_URL,DEFAULT_TIME_ICON

    # get the days and display
    for (day,) in db.getDays(year, month):
        item=gui.ListItem("%s" % day, iconImage=DEFAULT_TIME_ICON,thumbnailImage=DEFAULT_TIME_ICON + ".png")
        item.setInfo( type="pictures", infoLabels={ "Title": "%s" % day })
        plugin.addDirectoryItem(handle = int(sys.argv[1]), url=BASE_URL+"?action=showDate&year=%s&month=%s&day=%s" % (year,month,day), listitem = item, isFolder = True)

def mainmenu():
    global BASE_URL,DEFAULT_TIME_ICON,DEFAULT_FOLDER_ICON

    item=gui.ListItem("Timeline", iconImage=DEFAULT_TIME_ICON,thumbnailImage=DEFAULT_TIME_ICON + ".png")
    item.setInfo(type="pictures", infoLabels={ "Title": "Timeline" })
    plugin.addDirectoryItem(handle = int(sys.argv[1]), url=BASE_URL+"?action=listYears", listitem = item, isFolder = True)
    
    item=gui.ListItem("Categories (Tags)", iconImage=DEFAULT_FOLDER_ICON,thumbnailImage=DEFAULT_FOLDER_ICON + ".png")
    item.setInfo(type="pictures", infoLabels={ "Title": "Categories" })
    plugin.addDirectoryItem(handle = int(sys.argv[1]), url=BASE_URL+"?action=listCategories", listitem = item, isFolder = True)

def main():
    params = sys.argv[2]
    process_params(get_params(params))
    plugin.endOfDirectory( handle = int(sys.argv[1]), succeeded = True )

def _debug(msg):
    xbmc.log("F-Spot: " + msg, xbmc.LOGDEBUG)

def _error(msg):
    xbmc.log("F-Spot: " + msg, xbmc.LOGERROR)

if __name__=="__main__":
    try:
        main()
    except Exception, e:
        print str(e)
        print traceback.print_exc()
